package xnj.lazydog.btcontroller.ControlViews;

import android.app.Activity;
import android.app.AlertDialog;
import android.bluetooth.BluetoothDevice;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

import android.text.format.DateFormat;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.SpinnerAdapter;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import xnj.lazydog.btcontroller.Bluetooth.BlueToothMaster;
import xnj.lazydog.btcontroller.BlueToothService;
import xnj.lazydog.btcontroller.ControlViews.ControlViews.ControlElement;
import xnj.lazydog.btcontroller.MyViews.IDBitmap;
import xnj.lazydog.btcontroller.MyViews.SideToolBar;
import xnj.lazydog.btcontroller.ObjectFile.ObjectFile;
import xnj.lazydog.btcontroller.R;



public class ControlActivity extends Activity {

    private static final String TAG = "ControlActivity";
    ControlView view;
    String fileName = "123.pro";
    SideToolBar sideToolBar;
    final int [] LINK_NUM = new int[]{1,1,1,1,1,1,2,2,6,1};


    SideToolBar.SideToolBarListener sideToolBarListener = new SideToolBar.SideToolBarListener() {
        @Override
        public void onToolEvent(int toolIndex) {
            view.editMode = toolIndex;
        }
        @Override
        public void onButtonEvent(int buttonIndex) {
            if(buttonIndex==0)
            {
                view.removeToy();
            }

            if(buttonIndex==3) {
                showAddToyDialog();

            }
            if(buttonIndex==2) {
                if(view.selectedToy==null)
                    Toast.makeText(ControlActivity.this,"请先选择一个控件",Toast.LENGTH_SHORT).show();
                else
                    showLinkDialog(LINK_NUM[view.selectedToy.options.uiType],view.selectedToy);
            }
            if(buttonIndex==1)
            {
                if(view.selectedToy!=null) {
                    //view.isDialogShowing = true;
                    view.selectedToy.showSettingsDialog(ControlActivity.this);
                }else
                    Toast.makeText(ControlActivity.this,"请先选择一个控件",Toast.LENGTH_SHORT).show();
            }

        }
        @Override
        public void onQuitEvent() {

            if(view.isForDesign) {
                finish();
                return;
            }
            finish();
        }
    };


    boolean isQuitDialogShowing = false;
    void showQuitDialog()
    {
        AlertDialog.Builder builder = new AlertDialog.Builder(ControlActivity.this);
        builder.setTitle("确定要退出调试？").setPositiveButton("是", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                finish();
            }
        }).setNegativeButton("否", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        }).setOnDismissListener(new DialogInterface.OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface dialog) {
                isQuitDialogShowing = false;
            }
        }).create().show();
        isQuitDialogShowing = true;
    }


    @Override
    public void onBackPressed() {

        if(view.isForDesign)
            finish();
        else {
            if (!isQuitDialogShowing)
                showQuitDialog();
            else
                finish();
        }
    }

    void showAddToyDialog()
    {
        view.isDialogShowing = true;

        View[] list;
        ViewGroup parent;
        View v;
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        v = LayoutInflater.from(this).inflate(R.layout.add_toy_dialog_portrait,null);
        builder.setView(v);
        parent = v.findViewById(R.id.toy_list);
        final AlertDialog dialog = builder.create();

        dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));

        list = new View[parent.getChildCount()];
        for(int i=0;i<list.length;i++)
        {
            final  int fi=i;
            list[i] = parent.getChildAt(i);
            list[i].setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    bigSmall(v);

                    view.addNewToy(new ViewOptions(fi));
                    dialog.dismiss();

                    if(view.selectedToy!=null)
                        uiHandler.throwLinkDialog(LINK_NUM[view.selectedToy.options.uiType],view.selectedToy,400);
                    Log.w(TAG, "onClick: "+fi);
                }
            });
        }
        dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface dialog) {
                view.isDialogShowing = false;
                view.postInvalidate();
            }
        });
        dialog.show();
    }


    class SpinnerDog extends BaseAdapter implements SpinnerAdapter{
        List<String> items = new ArrayList<>();

        public SpinnerDog()
        {
        }

        public void add(String s)
        {
            items.add(s);
            notifyDataSetChanged();
        }

        public void clear()
        {
            items.clear();
            notifyDataSetChanged();
        }

        public void setList(List<String> strings)
        {
            items = new ArrayList<>(strings);
            notifyDataSetChanged();
        }

        @Override
        public View getDropDownView(int position, View convertView, ViewGroup parent) {
            TextView view;
            if(convertView==null)
                view = new TextView(ControlActivity.this);
            else
                view = (TextView)convertView;
            view.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
            view.setPadding(0,20,0,20);
            view.setSingleLine(true);
            view.setMaxLines(1);
            view.setTextColor(0xff000000);
            view.setText(items.get(position));
            return view;
        }

        @Override
        public int getCount() {
            return items.size();
        }

        @Override
        public Object getItem(int position) {
            return items.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public boolean hasStableIds() {
            return false;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            TextView view;
            if(convertView==null)
                view = new TextView(ControlActivity.this);
            else
                view = (TextView)convertView;
            view.setTextColor(0xff000000);
            view.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
            view.setText(items.get(position));

            return view;
        }

        @Override
        public int getItemViewType(int position) {
            return 0;
        }

        @Override
        public int getViewTypeCount() {
            return 1;
        }

        @Override
        public boolean isEmpty() {
            return items.isEmpty();
        }
    };


    Spinner []data_dir_spinner = new Spinner[6];
    Spinner []data_type_spinner = new Spinner[6];
    Spinner []data_index_spinner = new Spinner[6];
    SpinnerDog [] spinnerDogs = new SpinnerDog[6];

    int iscnt=0;


    View spinner_view;
    public void showLinkDialog(final int item_num,final ControlElement toy)
    {
        if(toy==null) {
            view.isDialogShowing = false;
            return;
        }

        view.isDialogShowing = true;

        final ViewGroup []list = new ViewGroup[6];
        ViewGroup parent,little_parent;
        AlertDialog.Builder builder = new AlertDialog.Builder(this);

        spinner_view =LayoutInflater.from(this).inflate(R.layout.link_toy_dialog,null);

        if(spinner_view==null)
            return;
        builder.setView(spinner_view);
        parent = spinner_view.findViewById(R.id.link_toy_parent);

        iscnt = 0;
        for(int i=0;i<list.length;i++)
        {
            final int fi=i;
            final Link link;
            list[i] = (ViewGroup) parent.getChildAt(i);
            little_parent =(ViewGroup) list[i].getChildAt(1);

            data_dir_spinner[i] = (Spinner) little_parent.getChildAt(0);
            data_type_spinner[i] = (Spinner) little_parent.getChildAt(2);
            data_index_spinner[i] = (Spinner) little_parent.getChildAt(4);

            if(i>=item_num)
                list[i].setVisibility(View.GONE);
            else {
                list[i].setVisibility(View.VISIBLE);
                iscnt +=2;
                spinnerDogs[i] = new SpinnerDog();
                data_index_spinner[i].setAdapter(spinnerDogs[i]);
                link = toy.options.links[i];
                if(link!=null){ // link exists

                    data_dir_spinner[i].setSelection(link.dir);
                    data_type_spinner[i].setSelection(link.type);

                    if(link.dir==0)
                    {
                        spinnerDogs[i].setList(view.project.txData[link.type]);
                    }else
                    {
                        spinnerDogs[i].setList(view.project.rxData[link.type]);
                    }
                    spinnerDogs[i].add("不链接");
                    data_index_spinner[i].setSelection(link.index);

                }else{ // Link is empty
                    data_dir_spinner[i].setSelection(ViewOptions.DEFAULT_DATA_DIR[toy.options.uiType]);
                    data_type_spinner[i].setSelection(ViewOptions.DEFAULT_DATA_TYPE[toy.options.uiType]);
                    if(ViewOptions.DEFAULT_DATA_DIR[toy.options.uiType]==0)
                    {
                        spinnerDogs[i].setList(view.project.txData[ViewOptions.DEFAULT_DATA_TYPE[toy.options.uiType]]);
                    }else
                    {
                        spinnerDogs[i].setList(view.project.rxData[ViewOptions.DEFAULT_DATA_TYPE[toy.options.uiType]]);
                    }
                    spinnerDogs[i].add("不链接");
                    data_index_spinner[i].setSelection(spinnerDogs[i].items.size()-1);
                }

                data_dir_spinner[i].setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                    @Override
                    public void onItemSelected(AdapterView<?> parent, View vi, int position, long id) {

                        int type = data_type_spinner[fi].getSelectedItemPosition();
                        if(position==0)
                            spinnerDogs[fi].setList(view.project.txData[type]);
                        else
                            spinnerDogs[fi].setList(view.project.rxData[type]);
                        spinnerDogs[fi].add("不链接");

                        if(iscnt>0) {
                            iscnt--;
                            return;
                        }
                        if(spinnerDogs[fi].items.size()>1)
                            data_type_spinner[fi].performClick();

                    }
                    @Override
                    public void onNothingSelected(AdapterView<?> parent) {

                    }
                });
                data_type_spinner[i].setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                    @Override
                    public void onItemSelected(AdapterView<?> parent, View vie, int position, long id) {


                        int txrx = data_dir_spinner[fi].getSelectedItemPosition();
                        if(txrx==0)
                            spinnerDogs[fi].setList(view.project.txData[position]);
                        else
                            spinnerDogs[fi].setList(view.project.rxData[position]);

                        Log.w(TAG, "onItemSelected: "+txrx+"  "+position);
                        spinnerDogs[fi].add("不链接");

                        if(iscnt>0) {
                            iscnt--;
                            return;
                        }
                        if(spinnerDogs[fi].items.size()>1)
                        data_index_spinner[fi].performClick();
                    }
                    @Override
                    public void onNothingSelected(AdapterView<?> parent) {
                    }
                });




            }//// --当该项可见时
        }///// ---结束循环配置
        AlertDialog dialog = builder.create();

        if(dialog.getWindow()!=null)
            dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));


        dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface dialog) {

                int dir,type,index;
                for(int i=0;i<item_num;i++) {

                    dir = data_dir_spinner[i].getSelectedItemPosition();
                    type =  data_type_spinner[i].getSelectedItemPosition();
                    index =  data_index_spinner[i].getSelectedItemPosition();

                    if(dir==0)  // TX
                    {
                        if(index>=0&&index<view.project.txData[type].size())
                        {
                            toy.options.links[i] = new Link(dir,type,index);
                            toy.valuesName[i] = view.project.txData[type].get(index);
                            toy.linkedValues[i] = view.project.values[dir][type].get(index);
                        }else {
                            toy.options.links[i] = null;
                            toy.valuesName[i] = null;
                            toy.linkedValues[i] = null;
                        }
                    }else   // RX
                    {
                        if(index>=0&&index<view.project.rxData[type].size())
                        {
                            toy.options.links[i] = new Link(dir,type,index);
                            toy.valuesName[i] = view.project.rxData[type].get(index);
                            toy.linkedValues[i] = view.project.values[dir][type].get(index);
                        }else {
                            toy.options.links[i] = null;
                            toy.valuesName[i] = null;
                            toy.linkedValues[i] = null;
                        }
                    }
                }

                view.isDialogShowing = false;
                view.postInvalidate();

                if(toy.settingsAfterLink)
                    toy.showSettingsDialog(ControlActivity.this);

            }
        });
        dialog.show();


    }

    BlueToothMaster master;
    BlueToothMaster.BlueToothEventListener listener_before;
    BlueToothMaster.BlueToothEventListener listener_now = new BlueToothMaster.BlueToothEventListener() {
        @Override
        public void onPowerOn() {

        }

        @Override
        public void onScanningStarted() {

        }

        @Override
        public void onScannedDevice(List<BluetoothDevice> devices, BluetoothDevice newDevice) {

        }

        @Override
        public void onScanningFinished() {

        }

        @Override
        public void onPaired() {

        }

        @Override
        public void onConnected(BluetoothDevice device) {

        }

        @Override
        public void onDisConnected() {

        }

        @Override
        public void onPreSend(BlueToothMaster.TxPackage tp) {

            for(Value v:view.project.values[0][0])
                tp.add(v.getBoolean());
            for(Value v:view.project.values[0][1])
                tp.add(v.getByte());
            for(Value v:view.project.values[0][2])
                tp.add(v.getShort());
            for(Value v:view.project.values[0][3])
                tp.add(v.getInt());
            for(Value v:view.project.values[0][4])
                tp.add(v.getFloat());
            //Log.w(TAG, "onPreSend: preSend");
        }

        @Override
        public void onDataSent(byte[] b, int l) {

            Log.w(TAG, "onDataSent: ");
        }

        @Override
        public void onReceived(BlueToothMaster.RxPackage rp) {

            for(int i=0;i<view.project.values[1][0].size();i++)
            {
                view.project.values[1][0].get(i).set(rp.getBoolean(i));
            }
            for(int i=0;i<view.project.values[1][1].size();i++)
            {
                view.project.values[1][1].get(i).set(rp.getByte(i));
            }
            for(int i=0;i<view.project.values[1][2].size();i++)
            {
                view.project.values[1][2].get(i).set(rp.getShort(i));
            }
            for(int i=0;i<view.project.values[1][3].size();i++)
            {
                view.project.values[1][3].get(i).set(rp.getInteger(i));
            }
            for(int i=0;i<view.project.values[1][4].size();i++)
            {
                view.project.values[1][4].get(i).set(rp.getFloat(i));
            }

            for(int i=0;i<view.toys.size();i++)
            {
                view.toys.get(i).onRxData();
            }
            //Log.w(TAG, "onReceived OK");
        }
        @Override
        public void onReceived(byte[] bytes, int length) {

        }

        @Override
        public void onStatisticUpdated(BlueToothMaster.Statistic statistic) {
            if(tx!=null&&rx!=null&&err!=null)
            uiHandler.setStatistic(statistic);
        }
    };

    boolean isThrowingDialog = false;

    class  UIHandler extends Handler
    {
        final int MSG_STATISTIC = 0;
        final int MSG_SHOW_LINK = 1;

        BlueToothMaster.Statistic statistic;
        int item_num;
        ControlElement toy;

        void setStatistic(BlueToothMaster.Statistic statistic1)
        {
            statistic =statistic1;
            sendEmptyMessage(MSG_STATISTIC);
        }

        public void showLink(ControlElement element)
        {
            if(isThrowingDialog)
                return;
            isThrowingDialog = true;
            this.item_num = LINK_NUM[element.options.uiType];
            view.selectedToy = element;
            toy = element;
            sendEmptyMessage(MSG_SHOW_LINK);

        }

        void showPicture(boolean ok)
        {
            if(ok)
                Toast.makeText(ControlActivity.this,"波形保存到 调试器截图 文件夹",Toast.LENGTH_SHORT).show();
            else
                Toast.makeText(ControlActivity.this,"文件系统出问题了，保存不了",Toast.LENGTH_SHORT).show();
        }


        void throwLinkDialog(int num,ControlElement element,int ms)
        {
            if(isThrowingDialog)
                return;
            isThrowingDialog = true;

            item_num = num;
            toy = element;
            sendEmptyMessageDelayed(MSG_SHOW_LINK,ms);
        }


        @Override
        public void handleMessage(Message msg) {

            switch (msg.what)
            {
                case MSG_STATISTIC:
                    if(statistic.txRate<128)
                        tx.setText("Tx: "+statistic.txRate+"B/s");
                    else
                        tx.setText(String.format(Locale.getDefault(),"Tx: %3.2fKB/s",statistic.txRate/1024.0f));
                    if(statistic.rxRate<128)
                        rx.setText("Rx: "+statistic.rxRate+"B/s");
                    else
                        rx.setText(String.format(Locale.getDefault(),"Rx: %3.2fKB/s",statistic.rxRate/1024.0f));
                    err.setText("Err: "+statistic.errorRate+"B/s");
                    break;
                case MSG_SHOW_LINK:

                    showLinkDialog(item_num,toy);
                    isThrowingDialog = false;
                    break;

            }
        }
    }
    public UIHandler uiHandler = new UIHandler();


    void initBlueTooth()
    {

        master = BlueToothService.blueToothMaster;
        listener_before = master.getListener();
        master.setListener(listener_now);
        master.setRxStructure(
                view.project.values[1][0].size(),
                view.project.values[1][1].size(),
                view.project.values[1][2].size(),
                view.project.values[1][3].size(),
                view.project.values[1][4].size());

        if (view.project.transMode ==Project.TRANS_MODE_SEND_ALWAYS)
            master.setTxPeriod(view.project.transPeriodMs);
        else
            master.setTxPeriod(view.project.controlPeriodMs);
        master.setMode(1+view.project.transMode);

    }

    ControlView.ToyListener toyListener = new ControlView.ToyListener() {
        @Override
        public void onToyValueChanged() {
            if(view.project.transMode==Project.TRANS_MODE_SEND_ON_CONTROL)
                master.trigger(view.project.repeatTimes);
        }

        @Override
        public void onShowLink(ControlElement element) {

            uiHandler.showLink(element);
        }

        @Override
        public void onPicture(boolean ok) {

            uiHandler.showPicture(ok);
        }
    };


    LinearLayout state_bar;
    TextView tx,rx,err;

    void initTransStateBar(boolean en)
    {
        state_bar = findViewById(R.id.trans_state_layout);
        if(en)
        {
            state_bar.setVisibility(View.VISIBLE);
            tx = findViewById(R.id.control_tx_rate);
            rx = findViewById(R.id.control_rx_rate);
            err = findViewById(R.id.control_err_rate);
        }else
            state_bar.setVisibility(View.GONE);
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.control_layout);
        view = findViewById(R.id.controlView);

        sideToolBar = findViewById(R.id.sideToolBar);
        sideToolBar.controlView = view;
        sideToolBar.configure(R.drawable.delete,sideToolBarListener);
        view.isForDesign = getIntent().getBooleanExtra("to_design", false);

        fileName = getIntent().getStringExtra("fileName");
        Project p = (Project)ObjectFile.loadObject(this, fileName);
        if(p==null)
            p = new Project();
        view.init(p);

        initTransStateBar(!view.isForDesign);

        //if(p.transMode==Project.TRANS_MODE_SEND_ON_CONTROL)
            view.initToyValueListener(toyListener);

        if(view.isForDesign) {                   //// 调试模式下加入工具栏
            sideToolBar.addTool(R.drawable.move);
            sideToolBar.addTool(R.drawable.scale);
            sideToolBar.addTool(R.drawable.rotate);
            sideToolBar.addButton(R.drawable.trash_bin);
            sideToolBar.addButton(R.drawable.gear_white);
            sideToolBar.addButton(R.drawable.double_link);
            sideToolBar.addButton(R.drawable.add_data);
        }else         //// 非调试模式下，加入蓝牙通信功能
        {
            initBlueTooth();
        }

    }

    @Override
    protected void onDestroy() {

        if(!view.isForDesign) {
            if (listener_before != null)
                master.setListener(listener_before);
            master.setMode(BlueToothMaster.MODE_CHAT);
        }

        Bitmap cut = Bitmap.createBitmap(256,256, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(cut);

        int ox,oy;
        float scale;
        if(view.w > view.h)
        {
            ox = 0;
            oy = (int)((view.w - view.h)*128/view.w);
            scale = 256 / view.w;
        }else
        {
            oy = 0;
            ox = (int)((view.h - view.w)*128/view.h);
            scale = 256 / view.h;
        }

        //Log.w(TAG, "onDestroy: "+ox+"  "+oy+" " +scale );

        canvas.clipRect(ox-1,oy-1,257-ox,257-oy);
        canvas.translate(ox,oy);

        canvas.scale(scale,scale);
        view.isForDesign = false;
        view.isForSnap = true;
        view.draw(canvas);
        //view.info_alpha = 1;

        ObjectFile.saveBitmap(cut,fileName+".png");

        ObjectFile.saveObject(this, fileName, view.project);
        super.onDestroy();
    }


    void  bigSmall(final View view)
    {
        Animation a = AnimationUtils.loadAnimation(this,R.anim.big_small);
        final Animation b = AnimationUtils.loadAnimation(this,R.anim.big_small_2);

        a.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
            }
            @Override
            public void onAnimationEnd(Animation animation) {
                view.startAnimation(b);
            }
            @Override
            public void onAnimationRepeat(Animation animation) {
            }
        });
        view.startAnimation(a);
    }
}
